﻿using System.Threading.Tasks;

namespace Sidvall.Web.IO
{
    public class SystemContext
    {
        #region Public Members

        public Sidvall.Security.AuthorizationManager AuthorizationManager { get; set; }
        public Sidvall.IO.StorageManager StorageManager { get; set; }
        public StorageContext FileSystemContext { get; set; }
        public IStorageFactory FileSystemFactory { get; set; }
        public FileManager FileManager { get; set; }
        public FileSystemEntryManager FileSystemEntryManager { get; set; }
        public FolderManager FolderManager { get; set; }
        public ControllerManager ControllerManager { get; set; }

        #region ThrowIfNotAuthorizedAsync

        public async Task ThrowIfNotAuthorizedAsync(Store store, string resource, string action, string path)
        {
            Sidvall.Security.AuthorizationManager authorizationManager;

            if (store != null)
                authorizationManager = store.GetAuthorizationManager();
            else
                authorizationManager = this.AuthorizationManager;
            if (!await authorizationManager.IsAuthorizedAsync(resource, action, store.StoreId, path).ConfigureAwait(false))
                throw new Sidvall.Security.UnauthorizedException();
        }

        #endregion

        #endregion
        #region Factory Members

        #region Current

        private static readonly object _Mutex = new object();
        private static volatile SystemContext _Current;
        public static SystemContext Current
        {
            get
            {
                SystemContext item;

                if (_Current == null)
                {
                    lock (_Mutex)
                    {
                        if (_Current == null)
                        {
                            item = new SystemContext()
                            {
                                AuthorizationManager = Sidvall.SystemContext.Current.AuthorizationManager,
                                StorageManager = Sidvall.SystemContext.Current.SystemStorageManager,
                                FileSystemContext = new StorageContext(),
                                FileSystemFactory = new StorageFactory(),
                                FileManager = new FileManager(),
                                FileSystemEntryManager = new FileSystemEntryManager(),
                                FolderManager = new FolderManager(),
                                ControllerManager = new ControllerManager(),
                            };
                            _Current = item;
                        }
                    }
                }
                return _Current;
            }
            set
            {
                lock (_Mutex)
                {
                    _Current = value;
                }
            }
        }

        #endregion

        #endregion
        #region Constructors

        public SystemContext()
        {
        }

        #endregion
    }
}
